package com.bigknow.appstore.web.base.service.impl;

import com.bigknow.appstore.common.AppStoreRuntimeException;
import com.bigknow.appstore.web.base.dao.IUserDao;
import com.bigknow.appstore.web.base.entity.Role;
import com.bigknow.appstore.web.framework.security.SecInfo;
import com.bigknow.appstore.web.framework.util.GlobalConstant;
import com.bigknow.appstore.web.base.entity.User;
import com.bigknow.appstore.web.base.service.IUserService;
import com.bigknow.appstore.web.base.vo.FancyTreeVo;
import com.bigknow.appstore.web.framework.service.BaseCRUDService;
import com.bigknow.appstore.web.framework.util.SecUtils;
import com.bigknow.fusion.common.inf.server.appstore.FusionHandler;
import com.bigknow.fusion.web.base.entity.enums.State;
import org.apache.commons.lang3.StringUtils;
import org.mongodb.morphia.Datastore;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * Not load reference object。
 */
@Service
public class UserService extends BaseCRUDService<User, IUserDao> implements IUserService {

    @Autowired
    private Datastore datastore;

    @Autowired
    private FusionService fusionService;


    private void encryptPassword(User user) {
        String password = SecUtils.encryptPassword(springUtils.getBeanByType(SecInfo.class), user.getPassword(),
                user.getId() + GlobalConstant.SECURITY_SALT);
        user.setPassword(password);
    }

    @Override
    public int save(User entity) {
        User old = get(entity.getId());
        if (old == null || !old.getPassword().equals(entity.getPassword())) encryptPassword(entity);

        if (isAppManager(entity) || isStoreUser(entity)) {
            FusionHandler fusionHandler = fusionService.getFusionHandler();

            com.bigknow.fusion.web.base.entity.User user = new com.bigknow.fusion.web.base.entity.User();

            user.setId(entity.getId());
            user.setName(entity.getName());
            user.setAccount(entity.getAccount());
            user.setAddress(entity.getAddress());
            user.setPassword(entity.getPassword());
            user.setState(State.valueOf(entity.getState().name()));
            if (isAppManager(entity)) {
                user.setRoleIds("5");
            } else {
                user.setRoleIds("2");
            }
            if (old == null) {
                if (fusionHandler.userExists(user)) {
                    throw new AppStoreRuntimeException(String.format("用户账号[%s]已存在", user.getAccount()));
                }
                fusionHandler.saveUser(user);
            } else {
                if (!fusionHandler.userExists(user)) {
                    throw new AppStoreRuntimeException(String.format("用户账号[%s]不存在", user.getAccount()));
                }
                fusionHandler.updateUser(user);
            }

        }

        return super.save(entity);
    }

    private boolean isAppManager(User user) {
        String[] ids = user.getRoleIds().split(",");
        return Arrays.binarySearch(ids, "2") >= 0;
    }

    private boolean isStoreUser(User user) {
        String[] ids = user.getRoleIds().split(",");
        return Arrays.binarySearch(ids, "4") >= 0;
    }

    @Override
    public int delete(String id) {
        User user = datastore.get(User.class, id);
        if (isAppManager(user) || isStoreUser(user)) {
            FusionHandler fusionHandler = fusionService.getFusionHandler();
            fusionHandler.deleteUser(id);
        }

        return super.delete(id);
    }

    @Override
    public List<FancyTreeVo> findAllForTree() {
        List<FancyTreeVo> users = new ArrayList<>();
        this.findAll().forEach(x -> {
            users.add(new FancyTreeVo(x.getId(), x.getName()));
        });

        return users;
    }

    @Override
    public boolean isSysManager(String userId) {
        User user = datastore.find(User.class).filter("id", userId).get();
        if (Arrays.asList(StringUtils.split(user.getRoleIds(), ",")).contains("1")) {
            return true;
        }
        return false;
    }

    public static void main(String[] args) {
        SecInfo secInfo = new SecInfo();
        secInfo.setHashAlgorithmName("md5");
        secInfo.setHashIterations("2");

        String orgPassword = "admin";
        String userId = "1";
        String password = SecUtils.encryptPassword(secInfo, orgPassword,
                userId + GlobalConstant.SECURITY_SALT);
        System.out.println("Encrypt password = " + password);
    }
}
